Skip to content

Playwright: extend test coverage to kb article helpfulness voting #6648

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions playwright_tests/core/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ def __init__(self, page: Page):
discussion_thread_data = json.load(discussion_thread_data_file)
discussion_thread_data_file.close()

with open("test_data/ga4_data.json", "r") as ga4_data_file:
ga4_data = json.load(ga4_data_file)
ga4_data_file.close()

# Fetching user secrets from GH.
user_secrets_accounts = {
"TEST_ACCOUNT_12": os.environ.get("TEST_ACCOUNT_12"),
Expand Down Expand Up @@ -662,3 +666,13 @@ def get_csrfmiddlewaretoken(self) -> str:
"""
return self.page.evaluate("document.querySelector('input[name=csrfmiddlewaretoken]')"
".value")

def get_ga_logs(self, msg) -> dict:
"""
This helper function fetches the GA logs from the console and formats them into a dict
"""
message = msg.text.replace('\n', '')
if message.startswith('event:'):
return {"event": message.split(": ", 1)[1].rstrip(':')}
elif message.startswith('parameters:'):
return {"parameters": json.loads(message.split(": ", 1)[1])}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class KBArticlePageMessages:
KB_ARTICLE_RESTRICTED_BANNER = "This document is restricted."
KB_ARTICLE_NOT_READY_FOR_TRANSLATION_BANNER = ("Traduci un document în engleză care nu este "
"încă gata de localizare.")
KB_SURVEY_FEEDBACK = "Thanks for your feedback!"
KB_SURVEY_FEEDBACK_NO_ADDITIONAL_DETAILS = ("Thanks for voting! Your additional feedback "
"wasn't submitted.")

def get_template_error(self, article_title) -> str:
return (f'Documents in the Template category must have titles that start with '
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
class KBArticlePage(BasePage):
def __init__(self, page: Page):
super().__init__(page)

# General page locators.
self.article_breadcrumb = lambda breadcrumb_name: page.locator(
"ol#breadcrumbs").get_by_role("link", name=f"{breadcrumb_name}")
Expand Down Expand Up @@ -37,6 +38,18 @@ def __init__(self, page: Page):
self.editing_tools_show_history_option = page.get_by_role("link", name="Show History",
exact=True)

# Helpfulness widget
self.helpfulness_widget = page.locator("form[class='document-vote--form helpful']")
self.helpful_button = page.locator("button[class='btn helpful-button']")
self.unhelpful_button = page.locator("button[class='btn not-helpful-button']")
self.helpfulness_option = lambda option: page.locator(f'//label[text()="{option}"]')
self.comments_textarea_field = page.locator("//textarea[@name='comment']")
self.helpfulness_widget_cancel_button = page.locator(
"//div[@class='sumo-button-wrap align-full']/button[normalize-space(text())='Cancel']")
self.helpfulness_widget_submit_button = page.locator(
"//div[@class='sumo-button-wrap align-full']/button[normalize-space(text())='Submit']")
self.survey_message = page.locator("div[class='survey-message']")

# KB Article page content actions.
def click_on_a_particular_breadcrumb(self, breadcrumb_name: str):
self._click(self.article_breadcrumb(breadcrumb_name))
Expand Down Expand Up @@ -113,3 +126,28 @@ def click_on_editing_tools_discussion_option(self):

def get_url(self) -> str:
return self._get_current_page_url()

# Helpfulness widget actions.
def is_helpfulness_widget_displayed(self) -> bool:
return self._is_element_visible(self.helpfulness_widget)

def click_on_helpful_button(self):
self._click(self.helpful_button)

def click_on_unhelpful_button(self):
self._click(self.unhelpful_button)

def click_on_helpfulness_option(self, option: str):
self._click(self.helpfulness_option(option))

def fill_helpfulness_textarea_field(self, text: str):
self._fill(self.comments_textarea_field, text)

def click_on_helpfulness_cancel_button(self):
self._click(self.helpfulness_widget_cancel_button)

def click_on_helpfulness_submit_button(self):
self._click(self.helpfulness_widget_submit_button)

def get_survey_message_text(self) -> str:
return self._get_text_of_element(self.survey_message)
104 changes: 104 additions & 0 deletions playwright_tests/test_data/ga4_data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"open_survey_helpful": {
"event": "article_survey_opened",
"parameters": {
"survey_type": "helpful"
}
},
"open_survey_unhelpful": {
"event": "article_survey_opened",
"parameters": {
"survey_type": "unhelpful"
}
},
"cancel_survey": {
"event": "article_survey_closed",
"parameters": {
"survey_type": "helpful"
}
},
"article_helpfulness": {
"event": "article_vote",
"parameters": {
"vote": "helpful"
}
},
"article-is-accurate": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "helpful",
"reason": "article-accurate"
}
},
"article-is-easy-to-understand": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "helpful",
"reason": "article-easy-to-understand"
}
},
"the-visuals-are-helpful": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "helpful",
"reason": "article-helpful-visuals"
}
},
"article-provided-the-information-i-needed": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "helpful",
"reason": "article-informative"
}
},
"other": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "helpful",
"reason": "other"
}
},
"article_unhelpfulness": {
"event": "article_vote",
"parameters": {
"vote": "not-helpful"
}
},
"article-is-inaccurate": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "unhelpful",
"reason": "article-inaccurate"
}
},
"article-is-confusing": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "unhelpful",
"reason": "article-confusing"
}
},
"missing-unclear-or-unhelpful-visuals": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "unhelpful",
"reason": "article-not-helpful-visuals"
}
},
"article-didn-t-provide-the-information-i-needed": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "unhelpful",
"reason": "article-not-informative"
}
},
"other-unhelpful": {
"event": "article_survey_submitted",
"parameters": {
"survey_type": "unhelpful",
"reason": "other"
}
}
}


Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import pytest
import re
from playwright.sync_api import expect, Page
from slugify import slugify

from playwright_tests.core.utilities import Utilities
from playwright_tests.messages.auth_pages_messages.fxa_page_messages import FxAPageMessages
from playwright_tests.messages.explore_help_articles.kb_article_page_messages import (
Expand Down Expand Up @@ -1741,3 +1743,140 @@ def test_article_topic_and_product_change(page: Page):
with allure.step("Deleting the article"):
utilities.navigate_to_link(article_details["article_url"])
sumo_pages.kb_article_deletion_flow.delete_kb_article()


# C2550394 C2877651 C2877652 C2877653 C2877654
@pytest.mark.kbArticleCreationAndAccess
@pytest.mark.parametrize("vote_type", ["Article is accurate", "Article is easy to understand",
"The visuals are helpful",
"Article provided the information I needed", "Other"])
def test_article_helpfulness_votes(page: Page, vote_type):
utilities = Utilities(page)
sumo_pages = SumoPages(page)
events = {}
ga_events = utilities.ga4_data

with allure.step("Sign in with an Admin account"):
utilities.start_existing_session(utilities.username_extraction_from_email(
utilities.user_secrets_accounts["TEST_ACCOUNT_MODERATOR"]
))

with allure.step("Create a new simple article"):
sumo_pages.submit_kb_article_flow.kb_article_creation_via_api(
page=page, approve_revision=True)
sumo_pages.kb_article_page.click_on_article_option()

with allure.step("Sign in with an normal account"):
utilities.start_existing_session(utilities.username_extraction_from_email(
utilities.user_secrets_accounts["TEST_ACCOUNT_12"]
))

with allure.step(f"Voting the article as {vote_type}"):
page.on("console", lambda msg: events.update(log) if (log := utilities.get_ga_logs(
msg)) is not None and msg.type == "log" else None)

sumo_pages.kb_article_page.click_on_helpful_button()
with check, allure.step("Verifying that the correct event is sent"):
check.is_true(events.items() <= ga_events['article_helpfulness'].items())

sumo_pages.kb_article_page.click_on_helpfulness_option(vote_type)
with check, allure.step("Verifying that the correct survey open event is sent"):
check.is_true(events.items() <= ga_events['open_survey_helpful'].items())

sumo_pages.kb_article_page.fill_helpfulness_textarea_field("Playwright vote test")

sumo_pages.kb_article_page.click_on_helpfulness_submit_button()
with check, allure.step("Verifying that the correct survey submitted event is sent"):
check.is_true(events.items() <= ga_events[f'{slugify(vote_type).lower()}'].items())

with check, allure.step("Verifying that the correct widget is displayed"):
check.equal(
sumo_pages.kb_article_page.get_survey_message_text(),
KBArticlePageMessages.KB_SURVEY_FEEDBACK
)

with check, allure.step("Waiting for 6 seconds and verifying that the widget is no longer"
" displayed"):
utilities.wait_for_given_timeout(6000)
check.is_false(sumo_pages.kb_article_page.is_helpfulness_widget_displayed())

with check, allure.step("Refreshing the page and verifying that the widget is no longer "
"displayed"):
page.reload()
check.is_false(sumo_pages.kb_article_page.is_helpfulness_widget_displayed())

with allure.step("Deleting the kb article"):
utilities.start_existing_session(utilities.username_extraction_from_email(
utilities.user_secrets_accounts["TEST_ACCOUNT_MODERATOR"]
))
sumo_pages.kb_article_deletion_flow.delete_kb_article()


# C2877656 C2877657 C2877658 C2877659 C2877660
@pytest.mark.kbArticleCreationAndAccess
@pytest.mark.parametrize("vote_type", ["Article is inaccurate", "Article is confusing",
"Missing, unclear, or unhelpful visuals",
"Article didn't provide the information I needed",
"Other"])
def test_article_unhelpfulness_votes(page: Page, vote_type):
utilities = Utilities(page)
sumo_pages = SumoPages(page)
events = {}
ga_events = utilities.ga4_data

with allure.step("Sign in with an Admin account"):
utilities.start_existing_session(utilities.username_extraction_from_email(
utilities.user_secrets_accounts["TEST_ACCOUNT_MODERATOR"]
))

with allure.step("Create a new simple article"):
sumo_pages.submit_kb_article_flow.kb_article_creation_via_api(
page=page, approve_revision=True)
sumo_pages.kb_article_page.click_on_article_option()

with allure.step("Sign in with an normal account"):
utilities.start_existing_session(utilities.username_extraction_from_email(
utilities.user_secrets_accounts["TEST_ACCOUNT_12"]
))

with allure.step(f"Voting the article as {vote_type}"):
page.on("console", lambda msg: events.update(log) if (log := utilities.get_ga_logs(
msg)) is not None and msg.type == "log" else None)

sumo_pages.kb_article_page.click_on_unhelpful_button()
with check, allure.step("Verifying that the correct event is sent"):
check.is_true(events.items() <= ga_events['article_unhelpfulness'].items())

sumo_pages.kb_article_page.click_on_helpfulness_option(vote_type)
with check, allure.step("Verifying that the correct survey open event is sent"):
check.is_true(events.items() <= ga_events['open_survey_unhelpful'].items())

sumo_pages.kb_article_page.fill_helpfulness_textarea_field("Playwright vote test")

sumo_pages.kb_article_page.click_on_helpfulness_submit_button()
with check, allure.step("Verifying that the correct survey submitted event is sent"):
check.is_true(events.items() <= ga_events[
f'{slugify(vote_type).lower() if vote_type != "Other" else "other-unhelpful"}'
].items())

with check, allure.step("Verifying that the correct widget is displayed"):
check.equal(
sumo_pages.kb_article_page.get_survey_message_text(),
KBArticlePageMessages.KB_SURVEY_FEEDBACK
)

with check, allure.step("Waiting for 6 seconds and verifying that the widget is no longer"
" displayed"):
utilities.wait_for_given_timeout(6000)
check.is_false(sumo_pages.kb_article_page.is_helpfulness_widget_displayed())

with check, allure.step("Refreshing the page and verifying that the widget is no longer "
"displayed"):
page.reload()
check.is_false(sumo_pages.kb_article_page.is_helpfulness_widget_displayed())

with allure.step("Deleting the kb article"):
utilities.start_existing_session(utilities.username_extraction_from_email(
utilities.user_secrets_accounts["TEST_ACCOUNT_MODERATOR"]
))
sumo_pages.kb_article_deletion_flow.delete_kb_article()